#include "mid_button.h"
#include "usart.h"

struct Button btn_left;
struct Button btn_right;
struct Button btn_up;
struct Button btn_down;
struct Button btn_enter;

// 全局组合键状态
typedef struct
{
    uint8_t is_active;     // 组合键是否激活
    uint8_t key1_id;       // 组合键第一个按键ID
    uint8_t key2_id;       // 组合键第二个按键ID
    uint32_t press_time;   // 组合键按下时间
    uint8_t key1_released; // 键1是否已松开
    uint8_t key2_released; // 键2是否已松开
} ComboState;

static ComboState active_combo = {0};
static uint32_t combo_timeout = 500; // 组合键时间阈值(ms)

// 组合键回调函数指针
static void (*combo_press_down_cb)(uint8_t, uint8_t) = NULL;
static void (*combo_press_up_cb)(uint8_t, uint8_t) = NULL;

// 注册组合键回调函数
void button_attach_combo(void (*press_down_cb)(uint8_t, uint8_t),
                         void (*press_up_cb)(uint8_t, uint8_t))
{
    combo_press_down_cb = press_down_cb;
    combo_press_up_cb = press_up_cb;
}

uint8_t read_button_GPIO(uint8_t button_id)
{
    // you can share the GPIO read function with multiple Buttons
    switch (button_id)
    {
    case btn_left_id:
        return HAL_GPIO_ReadPin(GPIOC, KEY1_Pin);
    case btn_right_id:
        return HAL_GPIO_ReadPin(GPIOC, KEY2_Pin);
    case btn_up_id:
        return HAL_GPIO_ReadPin(GPIOC, KEY3_Pin);
    case btn_down_id:
        return HAL_GPIO_ReadPin(GPIOC, KEY4_Pin);
    case btn_enter_id:
        return HAL_GPIO_ReadPin(GPIOC, KEY5_Pin);
    default:
        return 0;
    }
}
// 检查按钮是否按下（需要根据您的实现来完善）
uint8_t is_button_pressed(uint8_t button_id)
{
    if (button_id == btn_left_id)
    {
        return HAL_GPIO_ReadPin(GPIOC, KEY1_Pin);
    }
    else if (button_id == btn_right_id)
    {
        return HAL_GPIO_ReadPin(GPIOC, KEY2_Pin);
    }
    else if (button_id == btn_up_id)
    {
        return HAL_GPIO_ReadPin(GPIOC, KEY3_Pin);
    }
    else if (button_id == btn_down_id)
    {
        return HAL_GPIO_ReadPin(GPIOC, KEY4_Pin);
    }
    else if (button_id == btn_enter_id)
    {
        return HAL_GPIO_ReadPin(GPIOC, KEY5_Pin);
    }
		return 0;
}

// 检查是否有组合键激活
uint8_t check_combo_event(struct Button *handle, uint8_t event_type)
{
    static uint32_t last_press_time = 0;
    static uint8_t last_pressed_id = 0;
    uint8_t ret = 0;

    // 如果是按下事件
    if (event_type == PRESS_DOWN)
    {
        // 如果已经有组合键激活，不再处理新的组合键
        if (active_combo.is_active)
        {
            return 0;
        }

        uint32_t current_time = HAL_GetTick();

        // 检查是否在时间窗口内有两个键按下
        if (last_pressed_id != 0 &&
            last_pressed_id != handle->button_id &&
            (current_time - last_press_time) < combo_timeout)
        {
            // 激活组合键
            active_combo.is_active = 1;
            active_combo.key1_id = last_pressed_id;
            active_combo.key2_id = handle->button_id;
            active_combo.key1_released = 0;
            active_combo.key2_released = 0;

            // 触发组合键按下事件
            if (combo_press_down_cb)
            {
                combo_press_down_cb(active_combo.key1_id, active_combo.key2_id);
            }

            // 重置记录
            last_pressed_id = 0;
            last_press_time = 0;

            // 标记为组合键事件
            ret = 1;
        }
        else
        {
            // 记录当前按键信息
            last_pressed_id = handle->button_id;
            last_press_time = current_time;
        }
    }
    // 如果是松开事件
    else if (event_type == PRESS_UP)
    {
        // 如果组合键激活且当前按键是组合键的一部分
        if (active_combo.is_active)
        {
            if (handle->button_id == active_combo.key1_id)
            {
                active_combo.key1_released = 1;
            }
            else if (handle->button_id == active_combo.key2_id)
            {
                active_combo.key2_released = 1;
            }

            // 如果两个键都已松开，触发组合键弹起事件
            if (active_combo.key1_released && active_combo.key2_released)
            {
                // 触发组合键松开事件
                if (combo_press_up_cb)
                {
                    combo_press_up_cb(active_combo.key1_id, active_combo.key2_id);
                }

                // 重置组合键状态
                active_combo.is_active = 0;
                active_combo.key1_id = 0;
                active_combo.key2_id = 0;
                active_combo.key1_released = 0;
                active_combo.key2_released = 0;

                ret = 1;
            }
            else
            {
                // 只有一个键松开，不触发任何事件
                ret = 1;
            }
        }
        else
        {
            // 单键松开，可能触发单击事件
            ret = 2;

            // 重置单键记录
            if (last_pressed_id == handle->button_id)
            {
                last_pressed_id = 0;
                last_press_time = 0;
            }
        }
    }

    return ret;
}

// 组合键按下回调
void combo_press_down_handler(uint8_t key1, uint8_t key2)
{
}

// 组合键松开回调
void combo_press_up_handler(uint8_t key1, uint8_t key2)
{
    event_machine_run(FSM_Event_ESC);
}

void BTN_LEFT_PRESS_DOWN_Handler(void *btn)
{
    // 添加组合键检测
    check_combo_event((Button *)btn, PRESS_DOWN);
}

void BTN_LEFT_PRESS_UP_Handler(void *btn)
{
    // 添加组合键检测
    if (check_combo_event((Button *)btn, PRESS_UP) == 2)
    {
        event_machine_run(FSM_Event_LEFT_PRESS_UP);
    }
}

void BTN_LEFT_SINGLE_Click_Handler(void *btn)
{
    // // 添加组合键检测
    // if (check_combo_event((Button *)btn, PRESS_UP) == 2)
    // {
    //     event_machine_run(FSM_Event_LEFT_PRESS_UP);
    // }
    // event_machine_run(FSM_Event_LEFT_SINGLE_Click);
}

void BTN_LEFT_LONG_PRESS_HOLD_Handler(void *btn)
{
}

void BTN_RIGHT_PRESS_DOWN_Handler(void *btn)
{
    // 添加组合键检测
    check_combo_event((Button *)btn, PRESS_DOWN);
}

void BTN_RIGHT_PRESS_UP_Handler(void *btn)
{

    // 添加组合键检测
    if (check_combo_event((Button *)btn, PRESS_UP) == 2)
    {
        event_machine_run(FSM_Event_RIGHT_PRESS_UP);
    }
}

void BTN_RIGHT_SINGLE_Click_Handler(void *btn)
{
    //     // 添加组合键检测
    // if (check_combo_event((Button *)btn, PRESS_UP) == 2)
    // {
    //     event_machine_run(FSM_Event_RIGHT_PRESS_UP);
    // }
    // event_machine_run(FSM_Event_RIGHT_SINGLE_Click);
}

void BTN_RIGHT_LONG_PRESS_HOLD_Handler(void *btn)
{
}

void BTN_UP_PRESS_DOWN_Handler(void *btn)
{
}

void BTN_UP_PRESS_UP_Handler(void *btn)
{
    event_machine_run(FSM_Event_UP_PRESS_UP);
}

void BTN_UP_SINGLE_Click_Handler(void *btn)
{
}

void BTN_UP_LONG_PRESS_HOLD_Handler(void *btn)
{
}

void BTN_DOWN_PRESS_DOWN_Handler(void *btn)
{
}

void BTN_DOWN_PRESS_UP_Handler(void *btn)
{
    event_machine_run(FSM_Event_DOWN_PRESS_UP);
}

void BTN_DOWN_SINGLE_Click_Handler(void *btn)
{
}

void BTN_DOWN_LONG_PRESS_HOLD_Handler(void *btn)
{
}

void BTN_ENTER_PRESS_DOWN_Handler(void *btn)
{
}

void BTN_ENTER_PRESS_UP_Handler(void *btn)
{
    event_machine_run(FSM_Event_ENTER_PRESS_UP);
}

void BTN_ENTER_SINGLE_Click_Handler(void *btn)
{
}

void BTN_ENTER_LONG_PRESS_HOLD_Handler(void *btn)
{
}

void mid_button_init(void)
{
    button_init(&btn_left, read_button_GPIO, 0, btn_left_id);
    button_attach(&btn_left, PRESS_DOWN, BTN_LEFT_PRESS_DOWN_Handler); // 按下
    button_attach(&btn_left, PRESS_UP, BTN_LEFT_PRESS_UP_Handler);     // 松开
    button_start(&btn_left);

    button_init(&btn_right, read_button_GPIO, 0, btn_right_id);
    button_attach(&btn_right, PRESS_DOWN, BTN_RIGHT_PRESS_DOWN_Handler); // 按下
    button_attach(&btn_right, PRESS_UP, BTN_RIGHT_PRESS_UP_Handler);     // 松开
    button_start(&btn_right);

    button_init(&btn_up, read_button_GPIO, 0, btn_up_id);
    button_attach(&btn_up, PRESS_DOWN, BTN_UP_PRESS_DOWN_Handler); // 按下
    button_attach(&btn_up, PRESS_UP, BTN_UP_PRESS_UP_Handler);     // 松开
    button_start(&btn_up);

    button_init(&btn_down, read_button_GPIO, 0, btn_down_id);
    button_attach(&btn_down, PRESS_DOWN, BTN_DOWN_PRESS_DOWN_Handler); // 按下
    button_attach(&btn_down, PRESS_UP, BTN_DOWN_PRESS_UP_Handler);     // 松开
    button_start(&btn_down);

    button_init(&btn_enter, read_button_GPIO, 0, btn_enter_id);
    button_attach(&btn_enter, PRESS_DOWN, BTN_ENTER_PRESS_DOWN_Handler); // 按下
    button_attach(&btn_enter, PRESS_UP, BTN_ENTER_PRESS_UP_Handler);     // 松开
    button_start(&btn_enter);

    // 注册组合键事件
    button_attach_combo(combo_press_down_handler, combo_press_up_handler);
    // make the timer invoking the button_ticks() interval 5ms.
    // This function is implemented by yourself.
}
